package com.zhenwei.zscm.config.interceptors;

import com.zhenwei.zscm.common.exception.CustomException;
import com.zhenwei.zscm.common.base.RestResult;
import com.zhenwei.zscm.common.exception.UnauthorizedException;
import com.zhenwei.zscm.repo.ExceptionLogRepo;
import jakarta.validation.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

import java.util.Arrays;

@ControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    private ExceptionLogRepo exceptionLogRepo;

    @ExceptionHandler(value = CustomException.class)
    @ResponseBody
    public RestResult handleCustomException(CustomException e) {
        exceptionLogRepo.createAsync("CustomException", e.getMessage(), Arrays.toString(e.getStackTrace()));
        return RestResult.error(e.getMessage());
    }
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseBody
    public RestResult handleUnauthorizedException(UnauthorizedException e) {
        exceptionLogRepo.createAsync("UnauthorizedException", e.getMessage(), Arrays.toString(e.getStackTrace()));
        return RestResult.unauthorized(e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public RestResult handleValidationException(MethodArgumentNotValidException ex) {
        String defaultMessage = ex.getBindingResult().getAllErrors().getFirst().getDefaultMessage();
        return RestResult.fail(defaultMessage);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public RestResult handleValidationException(ConstraintViolationException ex) {
        StringBuilder sb = new StringBuilder();
        ex.getConstraintViolations().forEach(x->{
            sb.append(x.getMessage()).append(System.lineSeparator());
        });
        return RestResult.fail(sb.toString());
    }
    @ExceptionHandler(HandlerMethodValidationException.class)
    @ResponseBody
    public RestResult handleValidationException(HandlerMethodValidationException ex) {
        StringBuilder sb = new StringBuilder();
        ex.getAllErrors().forEach(x->{
            sb.append(x.getDefaultMessage()).append(System.lineSeparator());
        });
        return RestResult.fail(sb.toString());
    }
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public RestResult handleCustomException(RuntimeException e) {
        exceptionLogRepo.createAsync("RuntimeException", e.getMessage(), Arrays.toString(e.getStackTrace()));
        return RestResult.error(e.getMessage());
    }
}
